package com.bawei.library_common.websocket;

import android.os.Handler;
import android.text.TextUtils;

import com.bawei.library_common.utils.LoggerUtils;
import com.bawei.library_log.Logger;

import org.java_websocket.handshake.ServerHandshake;

import java.net.URI;

/**
 * @Author : 
 * @Time : On 2023/6/28 10:54
 * @Description : WebSocketUtils
 */
public class WebSocketUtils {
    public YaoWebSocketClient mSocketClient;
    private String websocket_url="124.70.98.255:8083/api/websocket/100";//默认网址
    private ReceiveMsgListener listener;
    private WebSocketUtils(String websocket_url, ReceiveMsgListener listener) {
        if(!TextUtils.isEmpty(websocket_url)){
            this.websocket_url = websocket_url;
        }
        this.listener = listener;
        initWS();
    }

    /**
     * 初始化YaoWebSocketClient
     */
    private void initWS() {
        //开启心跳链接的开关
        mHandler.postDelayed(heartBeatRunnable,HEART_BEAT_RATE);
        if(mSocketClient == null){//为空 创建socket
            initWebSocket();
        }else if(mSocketClient.isClosed()){//不为空，断开-》再次链接
            reconnectWs();//进入页面发现断开开启重连
        }

    }
    /**
     * 初始化WebSocket
     */
    private void initWebSocket() {
        LoggerUtils.Companion.i("webSocket","websocket的地址是：ws://"+websocket_url);
        URI uri = URI.create("ws://" + websocket_url);
        //TODO 创建websocket
        mSocketClient = new YaoWebSocketClient(uri){
            @Override
            public void onClose(int code, String reason, boolean remote) {
                super.onClose(code, reason, remote);
                LoggerUtils.Companion.i("webSocket", "websocket断开连接：·code:" + code + "·reason:" + reason + "·remote:" + remote);
                if (code!=1000) {
                    reconnectWs();//意外断开马上重连
                }
                if(listener != null){
                    listener.onClose(code, reason, remote);
                }
            }

            @Override
            public void onOpen(ServerHandshake handshakedata) {
                super.onOpen(handshakedata);
                LoggerUtils.Companion.i("webSocket", "websocket连接成功");
                if(listener != null){
                    listener.onOpen(handshakedata);
                }
            }

            @Override
            public void onMessage(String message) {
                super.onMessage(message);
                if(!"HeartBeat".equals(message)){//不是心跳消息
                    LoggerUtils.Companion.i("webSocket", "websocket收到消息：" + message);
                    mHandler.post(new Runnable() {//切换到主线程
                        @Override
                        public void run() {
                            if(listener != null){
                                listener.onReceive(message);
                            }
                        }
                    });


                }
            }

            @Override
            public void onError(Exception ex) {
                super.onError(ex);
                LoggerUtils.Companion.i("webSocket", "websocket链接失败：" + ex.getMessage());

                if(listener != null){
                    listener.onError(ex);
                }
            }
        };
        //TODO 设置超时时间
        mSocketClient.setConnectionLostTimeout(110 * 1000);
        //TODO 连接websocket
        new Thread() {
            @Override
            public void run() {
                try {
                    //connectBlocking多出一个等待操作，会先连接再发送，否则未连接发送会报错
                    mSocketClient.connectBlocking();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();


    }

    /**
     * 重连
     */
    private void reconnectWs() {
        mHandler.removeCallbacks(heartBeatRunnable);
        new Thread(new Runnable() {
            @Override
            public void run() {
                if(mSocketClient != null){
                    try {
                        LoggerUtils.Companion.i("webSocket","重连");
                        mSocketClient.reconnectBlocking();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    /**
     * 发送消息
     *
     * @param msg
     */
    public void sendMsg(String msg) {
        if (null != mSocketClient) {
           LoggerUtils.Companion.e("webSocket", String.format("Websocket发送的消息:%s",msg));
            if (mSocketClient.isOpen()) {
                mSocketClient.send(msg);
            }
        }
    }


    /**
     * 断开连接
     */
    private void closeConnect() {
        try {
            //关闭websocket
            if (null != mSocketClient) {
                mSocketClient.close();
            }
//            //停止心跳：防止内存泄漏
            if (mHandler != null) {
                mHandler.removeCallbacksAndMessages(null);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            mSocketClient = null;
        }
    }


    /**
     * WebSocket 心跳逻辑
     * 每隔10秒进行一次对长连接的心跳检测
     */
    private static final long HEART_BEAT_RATE = 10 * 1000;
    private Handler mHandler = new Handler();
    private Runnable heartBeatRunnable = new Runnable() {
        @Override
        public void run() {
            if (mSocketClient != null) {//不为空
                if (mSocketClient.isClosed()) {//断开链接
                    LoggerUtils.Companion.d("webSocket", "心跳包检测websocket连接状态1"+mSocketClient.isOpen() + "/" + websocket_url);
                    reconnectWs();//心跳机制发现断开开启重连
                } else {//没断开
                    LoggerUtils.Companion.d("webSocket", "心跳包检测websocket连接状态2"+mSocketClient.isOpen() + "/" + websocket_url);
                    sendMsg("Heartbeat");//发送一次心跳
                }
            } else {//为空
                LoggerUtils.Companion.d("webSocket",  "心跳包检测websocket连接状态重新连接");
                //如果client已为空，重新初始化连接
                mSocketClient = null;
                initWebSocket();
            }
            //每隔一定的时间，对长连接进行一次心跳检测
            mHandler.postDelayed(this, HEART_BEAT_RATE);
        }
    };




    /**
     * 构建者
     */

    public static class Builder{
        private String websocket_url;//网址
        private ReceiveMsgListener listener;//回调接口
        public Builder setWebsocket_url(String websocket_url) {
            this.websocket_url = websocket_url;
            return this;
        }

        public Builder setListener(ReceiveMsgListener listener) {
            this.listener = listener;
            return this;
        }

        public WebSocketUtils build(){
            return new WebSocketUtils(websocket_url,listener);
        }

    }

    /**
     * 接收到消息监听:接口回调
     */
    public interface ReceiveMsgListener{
        void onReceive(String message);
        void onOpen(ServerHandshake handshakedata);
        void onError(Exception ex);
        void onClose(int code, String reason, boolean remote);
    }
}
